/*
 * NetworkReader.java
 *
 * Created on 2005/01/22 +0900
 *
 * $Revision: 58 $
 * $Date: 2008-12-06 08:59:45 +0000 (Sat, 06 Dec 2008) $
 */

package org.gikolet.framework.io.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.gikolet.framework.util.Assert;

/**
 * @author Tetsutaro (latest modification by $Author: tetsutaro.ss $)
 * @version $Revision: 58 $ $Date: 2008-12-06 08:59:45 +0000 (Sat, 06 Dec 2008) $
 */
public class NetworkReader {
    private String uri;

    private HttpConnection httpConnection;

    public NetworkReader(String uri) throws IOException {
	Assert.isNotNull(uri);

	this.uri = uri;
    }

    public synchronized void open(HttpConnectionProvider provider)
	    throws IOException {
	Assert.isNotNull(provider);

	this.httpConnection = provider.openHttpConnection(getUri());
    }

    protected InputStream openInputStream() throws IOException {
	HttpConnection hc = this.httpConnection;
	if (hc == null) {
	    throw new IOException("no open");
	}

	int rc = hc.getResponseCode();
	if (rc != HttpConnection.HTTP_OK) {
	    throw new IOException("Response Code is " + rc);
	}
	return hc.openInputStream();
    }

    protected OutputStream openOutputStream() throws IOException {
	HttpConnection hc = this.httpConnection;
	if (hc == null) {
	    throw new IOException("no open");
	}
	hc.setRequestMethod(HttpConnection.POST);

	return hc.openOutputStream();
    }

    public synchronized void close() throws IOException {
	if (this.httpConnection == null) {
	    throw new IOException("no open");
	}
	this.httpConnection.close();
	this.httpConnection = null;
    }

    public synchronized boolean isOpen() {
	return this.httpConnection != null;
    }

    public void write(byte[] bytes) throws IOException {
	OutputStream outputStream = null;
	try {
	    outputStream = openOutputStream();
	    outputStream.write(bytes);
	} finally {
	    if (outputStream != null) {
		outputStream.close();
	    }
	}
    }

    public byte[] readToEnd() throws IOException {
	System.gc();

	InputStream inputStream = null;
	try {
	    inputStream = openInputStream();

	    ByteArrayOutputStream baos;
	    baos = new ByteArrayOutputStream();

	    byte[] buf = new byte[4096];
	    int t = 0;
	    while ((t = inputStream.read(buf)) != -1) {
		if (!isOpen()) {
		    throw new IOException("connect failed");
		}
		baos.write(buf, 0, t);
	    }

	    return baos.toByteArray();
	} finally {
	    if (inputStream != null) {
		inputStream.close();
	    }
	}
    }

    public String getUri() {
	return this.uri;
    }
}
